package com.lyf.scm.plan.domain.service.impl;


import com.github.pagehelper.PageInfo;
import com.lyf.scm.common.util.MD5Util;
import com.lyf.scm.plan.api.dto.EsAggregationDTO;
import com.lyf.scm.plan.api.dto.EsQueryDTO;
import com.lyf.scm.plan.api.dto.EsReturnDTO;
import com.lyf.scm.plan.domain.service.LazyLoadingService;
import lombok.Data;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.lyf.scm.plan.domain.service.impl.LazyLoadingServiceImpl.MemData.*;

/**
 * 列表查询懒加载service
 *
 * @author Martin
 * @date 2020-11-13 18:11
 */
@Service
public class LazyLoadingServiceImpl implements LazyLoadingService {

    @Data
    static class MemData {
        private Long userId;
        private String queryKey;
        private Set<String> skuSet;
        //private List<Object> dataList;
        private String afterKey;
        private EsQueryDTO esQuery;
        private int loadStatus;

        public static final int LOAD_STATUS_IDL = 1;
        public static final int LOAD_STATUS_DOING = 2;
        public static final int LOAD_STATUS_DONE = 3;
    }
    private String redis_cache_prefix_memdata_ = "scm-plan:memdata:";
    private String redis_cache_prefix_datalist_ = "scm-plan:datalist:";

    @Resource
    private RedisTemplate redisTemplate;

    public PageInfo<EsReturnDTO> pageQuery(EsAggregationDTO esAggregation) {
        // 根据查询条件生成请求key
        String queryKey = getQueryKey(esAggregation);
        // 取redis存的memData
        MemData memData = (MemData) redisTemplate.opsForValue().get(redis_cache_prefix_memdata_ + queryKey);
        if (memData == null) {
            memData.setQueryKey(queryKey);
            memData.setUserId(esAggregation.getUserId());
            Set<String> skuSet = new HashSet<>();// TODO 根据条件从es查询sku集合
            EsQueryDTO esQuery = esAggregation.getEsQuery();
            memData.setEsQuery(esQuery);
            memData.setLoadStatus(MemData.LOAD_STATUS_DOING);
            redisTemplate.opsForValue().set(redis_cache_prefix_memdata_ + queryKey, memData);
            //开始去es加载数据,加载5页，composite形式 TODO

            // 如果查询有结果，放入dataList
            List<EsReturnDTO> dataList = new ArrayList<>();

            // 根据加载结果设置afterKey和loadStatus

            // 重新设置memData
            redisTemplate.opsForValue().set(redis_cache_prefix_memdata_ + queryKey, memData);

            // 从dataList取出第一页数据返回
            PageInfo<EsReturnDTO> pageInfo = new PageInfo<>();
            pageInfo.setTotal(999);
            //...
            return pageInfo;
        } else {
            EsQueryDTO esQuery = esAggregation.getEsQuery();
//            Integer pageNum = esQuery.getPageNum();
//            Integer pageSize = esQuery.getPageSize();
            // 计算start和end
            int start = 0;
            int end = 10;
            //List<EsReturnDTO> list = redisTemplate.opsForList().range(redis_cache_prefix_datalist_ + queryKey, pageNum, pageSize);
            List<EsReturnDTO> list = redisTemplate.opsForList().range(redis_cache_prefix_datalist_ + queryKey, 0, 0);

            PageInfo<EsReturnDTO> pageInfo = new PageInfo<>();
            int loadStatus = memData.getLoadStatus();
            // 空闲
            if (LOAD_STATUS_IDL == loadStatus) {
                //TODO 要保证只有一个线程去加载数据
                String afterKey = memData.getAfterKey();
                // 去es从afterkey开始继续加载数据

                // 如果没有数据了，设置加载完状态
                memData.setLoadStatus(LOAD_STATUS_DONE);
            } else if (LOAD_STATUS_DOING == loadStatus) {
                // 等待1s后重新取，总共取5此
            } else {
                // 取完了，设置返回总条数
                Long size = redisTemplate.opsForList().size(redis_cache_prefix_datalist_ + queryKey);
//                pageInfo.setTotal(size / pageNum);//TODO 计算总页数
                pageInfo.setTotal(size / 0);//TODO 计算总页数
                pageInfo.setList(list);
            }
            return pageInfo;
        }
    }

    /**
     * 根据查询条件生成请求key
     * @param esAggregation
     * @return
     */
    private String getQueryKey(EsAggregationDTO esAggregation) {
        // 根据查询条件生成请求key
        EsQueryDTO esQuery = esAggregation.getEsQuery();
        String userId = esAggregation.getUserId() == null ? "" : esAggregation.getUserId().toString();
        String tableCode = esAggregation.getTableCode();
        return MD5Util.MD5(esQuery.toString() + userId + tableCode);
    }


}
